home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / gsdbloo.exe / GS_DBNDX.PAS < prev    next >
Pascal/Delphi Source File  |  1992-03-01  |  56KB  |  1,312 lines

  1. unit GS_DBNdx;
  2. {-----------------------------------------------------------------------------
  3.                            dBase III Index Handler
  4.  
  5.        GS_DBNdx Copyright (c)  Richard F. Griffin
  6.  
  7.        15 November 1990
  8.  
  9.        102 Molded Stone Pl
  10.        Warner Robins, GA  31088
  11.  
  12.        -------------------------------------------------------------
  13.        This unit handles the objects for all dBase III index (.NDX)
  14.        operations.
  15.  
  16.        changes:
  17.  
  18.           16 Nov 90 - Modified KeyUpdate sub-procedure KeyInsert to
  19.                       test for end-of-file during search for key.
  20.  
  21.           22 Apr 91 - Modified SetMatchValue to be a method.  This will
  22.                       ensure consistency in building character and numeric
  23.                       values.  Also modified throughout to ensure the full
  24.                       length was loaded into Ndx_Key_St for a field rather
  25.                       than just moving length(Work_Key) characters.
  26.                       Also added comments for KeyUpdate procedures.
  27.  
  28.           02 May 91 - Added an IndexSignature constant so the GS_dBase unit
  29.                       can confirm this unit is the dBase III index unit.
  30.  
  31.           01 Aug 91 -  Replaced string compare in DoMatchValue with call to
  32.                        GS_Sort_Compare for speed increase.
  33.  
  34.           15 Dec 91 - Fixed error in Ndx_GetRecPage that caused error in
  35.                       attempt to read Bttm_Record.
  36.  
  37.           02 Feb 92 - Added call to KeyLocRec in main part of KeyUpdate.
  38.                       This allows multiple indexes to be used.  In the past,
  39.                       the program assumed the index was pointing to the
  40.                       current record.  There is a sacrifice in update
  41.                       speed, however.
  42.  
  43.           19 Feb 92 - Embedded cache into Ndx_Get and Ndx_Put.  A number
  44.                       of node images will be stored to memory.  This will
  45.                       be treated as a stack, where the last page accessed
  46.                       will be pushed to the top and new nodes will use the
  47.                       bottom image.  They will replace the old image and
  48.                       push to the top.  This allows the most active nodes to
  49.                       remain in memory, with less active nodes being swapped
  50.                       out.  This also added a Ndx_Flush method to write all
  51.                       updated nodes to disk on demand, such as at closing.
  52.  
  53.                       Added KeyBOF flag for test for access beyond top of
  54.                       file.
  55.  
  56.           25 Feb 92 - Added call to unit GS_DBL.PAS to handle the routines
  57.                       to create and compare floating point types used in
  58.                       dBase indexes.  These routines save 10K of memory over
  59.                       the $N,E option for numeric coprocessor emulation.
  60.  
  61. ------------------------------------------------------------------------------}
  62.  
  63. {$D-}
  64. interface
  65.  
  66. uses
  67.    GS_Dbl,                            {handle double types}
  68.    GS_Strng,                          {String handler routines}
  69.    GS_Sort,                           {Sort/Compare routine}
  70.    GS_Error,                          {Error handler routines}
  71.    GS_FileH;                          {File handler routines}
  72.  
  73. const
  74.    NdxBufSize = 4096;
  75.    NdxBufferedPages = 32;
  76.    IndexSignature = 'NDX3';
  77.  
  78. type
  79.  
  80. {
  81.          ┌──────────────────────────────────────────────────────────┐
  82.          │  This record type describes the index file header.       │
  83.          │  This is a 512-byte block that is located at the         │
  84.          │  beginning of the index file.  Refer to Appendix C       │
  85.          │  for a description of the fields.                        │
  86.          └──────────────────────────────────────────────────────────┘
  87. }
  88.    GS_Indx_Head = Record
  89.                             Root        : Longint;
  90.                             Next_Blk    : Longint;
  91.                             Unknwn1     : Longint;
  92.                             Key_Lgth    : Integer;
  93.                             Max_Keys    : Integer;
  94.                             Data_Typ    : Integer;
  95.                             Entry_Sz    : Integer;
  96.                             Unknwn2     : Longint;
  97.                             Key_Form    : array [0..487] of char;
  98.                   end;
  99.  
  100. {
  101.          ┌──────────────────────────────────────────────────────────┐
  102.          │  This record type describes the index file node header.  │
  103.          │  Each node is a 512-byte block that is used as nodes     │
  104.          │  to store keys and pointers.  Refer to Appendix C        │
  105.          │  for a description of the fields.                        │
  106.          └──────────────────────────────────────────────────────────┘
  107. }
  108.  
  109.    GS_Indx_Data = Record
  110.                      Entry_Ct    : Integer;
  111.                      Unknwn1     : Integer;
  112.                      Data_Ary    : array [0..507] of byte;
  113.                                       {Memory array holding key entries}
  114.                      Filler1     : array [0..255] of byte;
  115.                                       {Filler for possible overflow during}
  116.                                       {insert mode.}
  117.                   end;
  118.  
  119.    GS_Indx_EntPtr = ^GS_Indx_Etry;    {Pointer of type GS_Indx_Etry.  Will}
  120.                                       {be used to reference key entries  }
  121.                                       {from GS_Indx_Data.Data_Ary.}
  122.  
  123. {
  124.          ┌──────────────────────────────────────────────────────────┐
  125.          │  This record type describes the index file key entries.  │
  126.          │  Refer to Appendix C for a description of each field.    │
  127.          └──────────────────────────────────────────────────────────┘
  128. }
  129.  
  130.    GS_Indx_Etry = Record
  131.                      Block_Ax : Longint;
  132.                      Recrd_Ax : Longint;
  133.                      Char_Fld : array [1..255] of char;
  134.                   end;
  135.  
  136. {
  137.           ┌────────────────────────────────────────────────────────┐
  138.           │  Work table used to step through nodes.  The previous  │
  139.           │  nodes must be saved for finding the next or previous  │
  140.           │  record during sequential reads.                       │
  141.           └────────────────────────────────────────────────────────┘
  142. }
  143.     GS_Indx_Tabl = Record
  144.                       Page_No  : Longint;   {Disk block holding node info}
  145.                       Etry_No  : Longint;   {Last entry used in node}
  146.                       Last_One : Longint;   {Number of keys in this node }
  147.                       Node_Pag : Boolean;   {True for non-leaf nodes}
  148.                    end;
  149.  
  150.    GS_DiskPagPtr = ^GS_DiskPagBfr;
  151.    GS_DiskPagBfr = array[0..511] of byte;
  152.  
  153.    GS_DiskTblPtr = ^GS_DiskTblPag;
  154.    GS_DiskTblPag = record
  155.       BlkNum : longint;
  156.       BlkWrt : boolean;
  157.       BlkPtr : GS_DiskPagPtr;
  158.    end;
  159.  
  160.    GS_Indx_LPtr = ^GS_dBase_IX;       {Pointer to object.  Used by GS_dBase_DB}
  161.  
  162. {
  163.                       ┌─────────────────────────────────┐
  164.                       │  GS_dBase_IX Object Definition  │
  165.                       └─────────────────────────────────┘
  166. }
  167.  
  168.    GS_dBase_IX = object
  169.       Ndx_Name     : String[64];      {File name of index file}
  170.       Ndx_Hdr      : GS_Indx_Head;    {Index header information}
  171.       Ndx_File     : file;            {File type for index file}
  172.       Ndx_Tabl     : array [0..25] of GS_Indx_Tabl;
  173.                                       {Array of 25 table entries to hold}
  174.                                       {the trail of non-leaf nodes that are}
  175.                                       {traversed during a key search.  This }
  176.                                       {table is needed to track positions for}
  177.                                       {sequential reads (next and previous).}
  178.  
  179.       Ndx_Lvl      : integer;         {Holds counter into Ndx_Tabl}
  180.       Ndx_Data     : GS_Indx_Data;    {Node header information}
  181.       Ndx_Pntr     : GS_Indx_EntPtr;  {Pointer to key entry information}
  182.       Ndx_Key_St   : string[127];     {Holds last key value found on call to}
  183.